package com.thz.system.service.user.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.thz.common.dto.ConversionRecordDTO;
import com.thz.common.dto.user.UserInfoDTO;
import com.thz.common.entity.UserInfo;
import com.thz.common.enums.ErrorCode;
import com.thz.common.exception.BusinessException;
import com.thz.common.utils.FileUtils;
import com.thz.system.mapper.user.UserInfoMapper;
import com.thz.system.service.user.IUserInfoService;
import com.thz.system.service.record.IConversionRecordService;
import com.thz.system.config.CosConfig;
import com.thz.system.utils.cos.CosFileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 用户信息服务实现类
 * 
 * @author THZ
 * @date 2025
 */
@Slf4j
@Service
public class UserInfoServiceImpl implements IUserInfoService {
    
    @Autowired
    private UserInfoMapper userInfoMapper;
    
    @Autowired
    private IConversionRecordService conversionRecordService;
    
    @Autowired
    private CosFileUtils cosFileUtils;
    
    @Autowired
    private CosConfig cosConfig;
    
    @Value("${app.domain:http://localhost:9091}")
    private String serverDomain;
    
    @Value("${file.avatar.path:./avatars}")
    private String avatarPath;

    private static final String avatarUrl = "https://api.dicebear.com/7.x/bottts/svg?seed=";
    
    @Override
    @Transactional
    public UserInfoDTO getOrCreateUser(String ipAddress) {
        // 查询用户是否存在
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getIpAddress, ipAddress);
        UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);
        
        // 如果不存在则创建新用户
        if (userInfo == null) {
            userInfo = new UserInfo();
            userInfo.setIpAddress(ipAddress);
            userInfo.setAvatarUrl(generateAvatarUrl(ipAddress));
            userInfo.setTotalConversions(0);
            userInfo.setLastVisitTime(LocalDateTime.now());
            userInfo.setCreateTime(LocalDateTime.now());
            userInfo.setUpdateTime(LocalDateTime.now());
            
            userInfoMapper.insert(userInfo);
            log.info("创建新用户: IP={}, ID={}", ipAddress, userInfo.getId());
        } else {
            // 更新最后访问时间
            updateLastVisitTime(ipAddress);
        }
        
        return convertToDTO(userInfo);
    }
    
    @Override
    @Transactional
    public void updateLastVisitTime(String ipAddress) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getIpAddress, ipAddress);
        UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);
        
        if (userInfo != null) {
            userInfo.setLastVisitTime(LocalDateTime.now());
            userInfoMapper.updateById(userInfo);
        }
    }
    
    @Override
    @Transactional
    public void incrementConversions(String ipAddress) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getIpAddress, ipAddress);
        UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);
        
        if (userInfo != null) {
            userInfo.setTotalConversions(userInfo.getTotalConversions() + 1);
            userInfo.setLastVisitTime(LocalDateTime.now());
            userInfoMapper.updateById(userInfo);
            log.info("用户转换次数+1: IP={}, 总次数={}", ipAddress, userInfo.getTotalConversions());
        }
    }
    
    @Override
    public List<ConversionRecordDTO> getUserConversionHistory(String ipAddress, int limit) {
        // 获取用户ID
        LambdaQueryWrapper<UserInfo> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.eq(UserInfo::getIpAddress, ipAddress);
        UserInfo userInfo = userInfoMapper.selectOne(userQueryWrapper);
        
        if (userInfo == null) {
            return List.of();
        }
        
        // 使用统一的转换记录服务查询所有类型的转换历史
        return conversionRecordService.getConversionHistoryByIp(ipAddress, limit);
    }
    
    @Override
    @Transactional
    public void deleteUserConversion(String ipAddress, Long recordId) {
        // 获取用户信息
        LambdaQueryWrapper<UserInfo> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.eq(UserInfo::getIpAddress, ipAddress);
        UserInfo userInfo = userInfoMapper.selectOne(userQueryWrapper);
        
        if (userInfo == null) {
            throw new BusinessException(ErrorCode.USER_NOT_EXISTS);
        }
        
        // 使用统一的转换记录服务删除记录
        conversionRecordService.deleteRecord(recordId);
        
        // 更新用户转换次数
        if (userInfo.getTotalConversions() > 0) {
            userInfo.setTotalConversions(userInfo.getTotalConversions() - 1);
            userInfoMapper.updateById(userInfo);
        }
        
        log.info("用户删除转换记录: IP={}, RecordId={}", ipAddress, recordId);
    }
    
    @Override
    public String generateAvatarUrl(String ipAddress) {
        // 使用DiceBear Avatars API生成头像
        // 基于IP地址生成一致的头像
        String seed = ipAddress.replaceAll("[^a-zA-Z0-9]", "");
        return avatarUrl + seed;
    }
    
    @Override
    @Transactional
    public UserInfoDTO uploadAvatar(String ipAddress, org.springframework.web.multipart.MultipartFile avatarFile) {
        // 1. 验证头像文件
        FileUtils.validateAvatarFile(avatarFile);
        
        // 2. 获取用户信息
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getIpAddress, ipAddress);
        UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);
        
        if (userInfo == null) {
            // 如果用户不存在，先创建用户
            userInfo = new UserInfo();
            userInfo.setIpAddress(ipAddress);
            userInfo.setTotalConversions(0);
            userInfo.setLastVisitTime(LocalDateTime.now());
            userInfo.setCreateTime(LocalDateTime.now());
            userInfo.setUpdateTime(LocalDateTime.now());
            userInfoMapper.insert(userInfo);
        }
        
        // 3. 删除旧头像（如果存在且不是默认头像）
        String oldAvatarUrl = userInfo.getAvatarUrl();
        if (oldAvatarUrl != null && !oldAvatarUrl.startsWith("http://api.dicebear.com")) {
            // 删除旧头像（自动判断COS或本地）
            cosFileUtils.deleteFile(oldAvatarUrl);
            log.info("删除旧头像: {}", oldAvatarUrl);
        }
        
        // 4. 保存新头像文件（上传到COS或本地）
        String avatarUrl = cosFileUtils.saveUploadFile(avatarFile, avatarPath, cosConfig.getAvatarPrefix());
        log.info("头像文件已保存: {}", avatarUrl);
        
        // 5. 更新用户头像URL（保存完整URL或本地路径）
        userInfo.setAvatarUrl(avatarUrl);
        userInfo.setLastVisitTime(LocalDateTime.now());
        userInfo.setUpdateTime(LocalDateTime.now());
        userInfoMapper.updateById(userInfo);
        
        log.info("用户上传头像: IP={}, URL={}", ipAddress, avatarUrl);
        
        // 6. 返回更新后的用户信息（包含完整的头像URL）
        return convertToDTO(userInfo);
    }
    
    /**
     * 转换为DTO
     */
    private UserInfoDTO convertToDTO(UserInfo userInfo) {
        UserInfoDTO dto = new UserInfoDTO();
        BeanUtil.copyProperties(userInfo, dto);
        
        // 将头像路径转换为访问URL（自动处理COS URL和本地路径）
        if (userInfo.getAvatarUrl() != null) {
            // 如果是外部URL（如DiceBear API或COS URL），直接使用
            if (userInfo.getAvatarUrl().startsWith("http://") || 
                userInfo.getAvatarUrl().startsWith("https://")) {
                dto.setAvatarUrl(userInfo.getAvatarUrl());
            } else {
                // 如果是本地文件路径，构建访问URL
                String avatarUrl = cosFileUtils.getFileUrl(userInfo.getAvatarUrl(), serverDomain + "/api/files/avatars/");
                dto.setAvatarUrl(avatarUrl);
            }
        } else {
            // 如果没有头像，生成默认头像
            dto.setAvatarUrl(generateAvatarUrl(userInfo.getIpAddress()));
        }
        
        return dto;
    }
}

